package com.eascs.web.o2o.quartz.dubbo;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import com.alibaba.dubbo.config.annotation.Service;
import com.eascs.scheduler.common.entity.ScheduleJob;
import com.eascs.scheduler.common.service.IDubboJobService;

@Service
public class DubboJobServiceImpl implements IDubboJobService, BeanFactoryAware {

	@Autowired
	SchedulerFactoryBean schedulerFactoryBean;

	private static BeanFactory beanFactory = null;

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		this.beanFactory = beanFactory;
	}

	/**
	 * 1.默认情况下，调度工厂取出的调度器都是一致的，类比于jdbc的session理解 2.调度器（一对多）任务（一对多）触发器
	 * 
	 */

	// 添加新任务
	@Override
	public void addScheduleJob(ScheduleJob job) {
		try {
			Scheduler scheduler = schedulerFactoryBean.getScheduler();
			// 1.新建一个基于Spring的管理Job类
			MethodInvokingJobDetailFactoryBean mjdfb = new MethodInvokingJobDetailFactoryBean();
			mjdfb.setName(job.getJobName());// 设置Job名称
			mjdfb.setGroup(Scheduler.DEFAULT_GROUP);
			// 如果定义的任务类为Spring的定义的Bean则调用 getBean方法
			if (job.getIsSpringbean().equals("1")) {
				mjdfb.setTargetObject(beanFactory.getBean(job.getClassPath()));// 设置任务类
			} else {// 否则直接new对象
				mjdfb.setTargetObject(Class.forName(job.getClassPath()).newInstance());// 设置任务类
			}
			mjdfb.setTargetMethod(job.getMethod());// 设置任务方法
			mjdfb.setConcurrent(job.getConcurrent().equals("0") ? false : true); // 设置是否并发启动任务
			mjdfb.afterPropertiesSet();// 将管理Job类提交到计划管理类
			// 2.将Spring的管理Job类转为Quartz管理Job类
			JobDetail jobDetail = mjdfb.getObject();
			jobDetail.getJobDataMap().put("scheduleJobInfo", job);
			// scheduler.addJob(jobDetail, true); // 将Job添加到管理类（此处若设置会导致重复注册）
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
			CronTrigger trigger = TriggerBuilder.newTrigger()
					.withIdentity(job.getTriggerName(), Scheduler.DEFAULT_GROUP).withSchedule(scheduleBuilder).build();
			scheduler.scheduleJob(jobDetail, trigger);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 更新任务（时间表达式）
	@Override
	public void updateScheduleJobByCron(ScheduleJob scheduleJob) {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();

		TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getTriggerName(), Scheduler.DEFAULT_GROUP);

		// 获取trigger，即在spring配置文件中定义的 bean id="myTrigger"
		CronTrigger trigger = null;
		try {
			trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
		} catch (SchedulerException e1) {
			e1.printStackTrace();
		}

		// 表达式调度构建器
		
		String cron = scheduleJob.getCronExpression();
		CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);

		// 按新的cronExpression表达式重新构建trigger
		trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

		// 按新的trigger重新设置job执行
		try {
			scheduler.rescheduleJob(triggerKey, trigger);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}

	// 暂停
	@Override
	public void pauseJob(ScheduleJob scheduleJob) {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), Scheduler.DEFAULT_GROUP);
		try {
			scheduler.pauseJob(jobKey);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}

	// 恢复
	@Override
	public void resumeJob(ScheduleJob scheduleJob) {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), Scheduler.DEFAULT_GROUP);
		try {
			scheduler.resumeJob(jobKey);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}

	// 删除
	@Override
	public void deleteJob(ScheduleJob scheduleJob) {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), Scheduler.DEFAULT_GROUP);
		try {
			scheduler.deleteJob(jobKey);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}

	// 立即运行任务
	@Override
	public void resumeJobNow(ScheduleJob scheduleJob) {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), Scheduler.DEFAULT_GROUP);
		try {
			scheduler.triggerJob(jobKey);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}

	}

	@Override
	public boolean isExistJob(ScheduleJob scheduleJob) {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), Scheduler.DEFAULT_GROUP);
		boolean flag =false;
		try {
			flag = scheduler.checkExists(jobKey);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		return flag;
	}

}
